package com.weige.mq.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@Slf4j
public class CommonConfig implements ApplicationContextAware {

    /**
     * 当前方法  会在项目启动时调用
     *
     * @param applicationContext IOC容器对象
     * @throws BeansException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        // 在容器中找到RabbitTemplate对象  设置     确认回调     return回调
        RabbitTemplate rabbitTemplate = applicationContext.getBean(RabbitTemplate.class);

        // 设置生产者确认回调函数
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            /**
             * @param correlationData  发消息时自定义的数据
             * @param ack  是否发送成功  true: 消息已经发送到交换机    false: 消息发送失败
             * @param cause  失败原因
             */
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                String id = correlationData.getId();
                if (ack) {
                    log.info(" 消息确认回调触发   消息已经成功发送到 mq的exchange中    消息id:{}", id);
                } else {
                    log.error(" 消息确认回调触发   消息发送失败    消息id:{}, 失败原因:{}", id, cause);

                    // 将消息  重新发送
                }
            }
        });

        rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
            /**
             * @param message  返还的消息内容
             * @param replyCode    回复状态码
             * @param replyText    回复内容
             * @param exchange     交换机
             * @param routingKey   路由
             */
            @Override
            public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
                // 投递失败，记录日志
                log.info("消息发送失败，应答码{}，原因{}，交换机{}，路由键{},消息{}",
                        replyCode, replyText, exchange, routingKey, message.toString());

                // 重试发送消息
            }
        });

    }

    @Bean
    DirectExchange simpleDirect() {
        return new DirectExchange("simple.direct", true, false);
    }

    @Bean
    Queue simpleQueue() {
        return new Queue("simple.queue", false);
    }

    @Bean
    Binding bindingSimpleQueue() {
        return BindingBuilder.bind(simpleQueue()).to(simpleDirect()).with("simple");
    }
}
